﻿using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

public class ToolsMenu
{
    public static string PicRefPath = "/Editor/Template/PicRef.txt";
    public static string PrefabRefPath = "/Editor/Template/PrefabRef.txt";
    public static string PicRefFullPath = "/Editor/Template/PicRefFull.txt";
    
    [MenuItem("Tools/UVConfigToUTF8", false, 30)]
    public static void UVConfigToUTF8()
    {
        string fullPath = Application.dataPath + "/Resources/Atlas";
        string[] files = Directory.GetFiles(fullPath, "*.txt", SearchOption.AllDirectories);
        for (int i = 0; i < files.Length; i++)
        {
            EditorUtility.DisplayProgressBar("正在转换...", files[i], (i + 1f) / files.Length);
            File.WriteAllText(files[i], File.ReadAllText(files[i], Encoding.Default), Encoding.UTF8);
        }
        EditorUtility.ClearProgressBar();
        AssetDatabase.Refresh();
    }

    [MenuItem("Tools/OneKey Bake", false, 20)]
    public static void Init()
    {
        LightmapEditorSettings.maxAtlasHeight = 512;
        LightmapEditorSettings.maxAtlasWidth = 512;
        Lightmapping.Clear();
        Lightmapping.Bake();
    }

    [MenuItem("GameEditor/分析预设引用资源", false, 50)]
    private static void AnalysisPrefabRes()
    {
        string fullPath = Application.dataPath + "/Resources";
        string[] dirs = Directory.GetFiles(fullPath, "*.prefab", SearchOption.AllDirectories);
        Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);

        dirs = new string[objs.Length];
        for (int i = 0; i < objs.Length; i++)
        {
            dirs[i] = AssetDatabase.GetAssetPath(objs[i]);
        }

        StringBuilder infos = new StringBuilder();
        List<string> texNames = new List<string>();
        List<string> matNames = new List<string>();
        List<string> meshNames = new List<string>();

        infos.Append("分析预设依赖资源\n\n");
        for (int i = 0; i < dirs.Length; i++)
        {
            texNames.Clear(); matNames.Clear(); meshNames.Clear();
            string goPath = dirs[i].Replace(Application.dataPath, "Assets");
            EditorUtility.DisplayProgressBar("处理中 请稍等", "正在处理：" + goPath, (i + 1f) / dirs.Length);

            infos.Append(string.Format("分析{0}\n\n", goPath));
            infos.Append("==================================================\n\n");
            string[] depends = AssetDatabase.GetDependencies(new string[1] { goPath });

            for (int idx = 0; idx < depends.Length; ++idx)
            {
                string depend = depends[idx];
                int dotPos = depend.LastIndexOf('.');
                if (dotPos > -1)
                {
                    string suffix = depend.Substring(dotPos + 1);
                    suffix = suffix.ToLower();
                    switch (suffix)
                    {
                        case "mat":
                            matNames.Add(depend);
                            break;
                        case "png":
                            texNames.Add(depend);
                            break;
                        case "tga":
                            texNames.Add(depend);
                            break;
                        case "fbx":
                            meshNames.Add(depend);
                            break;
                    }
                }
            }
            infos.Append("\t模型----------------------------------------->\n");
            for (int idx = 0; idx < meshNames.Count; ++idx)
            {
                infos.Append(string.Format("\t\t{0}\n", meshNames[idx]));
            }
            infos.Append("\t材质----------------------------------------->\n");
            for (int idx = 0; idx < matNames.Count; ++idx)
            {
                infos.Append(string.Format("\t\t{0}\n", matNames[idx]));
            }
            infos.Append("\t图片----------------------------------------->\n");
            for (int idx = 0; idx < texNames.Count; ++idx)
            {
                infos.Append(string.Format("\t\t{0}\n", texNames[idx]));
            }
            infos.Append("\n\n");
        }

        //AssetDatabase.SaveAssets(); AssetDatabase.Refresh();
        fullPath = Application.dataPath + PrefabRefPath;
        StreamWriter writer = new StreamWriter(fullPath, false, Encoding.UTF8);
        writer.Write(infos.ToString()); writer.Close();
        EditorUtility.ClearProgressBar();
    }

    [MenuItem("GameEditor/分析对象图片引用", false, 50)]
    private static void DispPicRef()
    {
        string fullPath = Application.dataPath + "/Resources";
        string[] dirs = Directory.GetFiles(fullPath, "*.prefab", SearchOption.AllDirectories);
        Dictionary<string, Dictionary<string, List<string>>> data = new Dictionary<string, Dictionary<string, List<string>>>();
        for (int i = 0; i < dirs.Length; i++)
        {
            string goPath = dirs[i].Replace(Application.dataPath, "Assets");
            EditorUtility.DisplayProgressBar("处理中 请稍等", "正在处理：" + goPath, (i + 1f) / dirs.Length);
            GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(goPath);
            UISprite[] sps = go.GetComponentsInChildren<UISprite>(true);

            if (sps.Length > 0)
            {
                for (int j = 0; j < sps.Length; ++j)
                {
                    UISprite sp = sps[j];
                    if (sp == null || sp.atlas == null || sp.spriteName == "") { continue; }
                    string path = string.Format("{0} ... {1}", goPath, sp.transform.name);
                    string atlasName = sp.atlas.name;
                    string spriteName = sp.spriteName;

                    if (!data.ContainsKey(atlasName))
                    {
                        data.Add(atlasName, new Dictionary<string, List<string>>());
                    }
                    if (!data[atlasName].ContainsKey(spriteName))
                    {
                        data[atlasName][spriteName] = new List<string>();
                    }
                    if (!data[atlasName][spriteName].Contains(path))
                    {
                        data[atlasName][spriteName].Add(path);
                    }
                }
            }
            //从scene下删除
            Object.DestroyImmediate(go);
        }
        StringBuilder sb = new StringBuilder();
        foreach (var p in data)
        {
            StringBuilder line = new StringBuilder();
            string atlas = p.Key;
            foreach (var q in p.Value)
            {
                string sprite = q.Key;
                line.Append(string.Format("【图集:{0}\\{1}】", atlas, sprite));
                for (int idx = 0; idx < p.Value[sprite].Count; ++idx)
                {
                    line.Append("\n\t\t\t\t");
                    line.Append(p.Value[sprite][idx]);
                }
                line.Append("\n");
            }
            sb.Append(line);
            sb.Append('\n');
        }
        //AssetDatabase.SaveAssets(); AssetDatabase.Refresh();
        fullPath = Application.dataPath + PicRefPath;
        StreamWriter writer = new StreamWriter(fullPath, false, Encoding.UTF8);
        writer.Write(sb.ToString()); writer.Close();
        EditorUtility.ClearProgressBar();
    }

    [MenuItem("GameEditor/全面分析图片引用", false, 50)]
    private static void DispPicRefFull()
    {
        string fullPath = Application.dataPath + "/Resources";
        string[] dirs = Directory.GetFiles(fullPath, "*.prefab", SearchOption.AllDirectories);
        Dictionary<string, List<string>> data = new Dictionary<string, List<string>>();

        string[] path = new string[1];
        for (int i = 0; i < dirs.Length; i++)
        {
            string goPath = dirs[i].Replace(Application.dataPath, "Assets");
            EditorUtility.DisplayProgressBar("处理中 请稍等", "正在处理：" + goPath, (i + 1f) / dirs.Length);
            path[0] = goPath; string[] deps = AssetDatabase.GetDependencies(path);

            for (int idx = 0; idx < deps.Length; ++idx)
            {
                string dep = deps[idx];
                string ext = Path.GetExtension(dep);
                ext = ext.ToLower();
                if (ext != ".png" && ext != ".tga")
                {
                    continue;
                }
                if (!data.ContainsKey(dep))
                {
                    data.Add(dep, new List<string>());
                }
                if (!data[dep].Contains(goPath))
                {
                    data[dep].Add(goPath);
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        foreach (var p in data)
        {
            sb.Append(string.Format("图片资源：{0}\n", p.Key));
            for (int idx = 0; idx < p.Value.Count; ++idx)
            {
                string refPrefab = p.Value[idx];
                sb.Append(string.Format("\t\t{0}\n", refPrefab));
            }
        }

        fullPath = Application.dataPath + PicRefFullPath;
        StreamWriter writer = new StreamWriter(fullPath, false, Encoding.UTF8);
        writer.Write(sb.ToString()); writer.Close();
        EditorUtility.ClearProgressBar();
    }
    
    [MenuItem("Tools/OneKey Light", false, 20)]
    public static void Light()
    {
        foreach (GameObject obj in Object.FindObjectsOfType(typeof(GameObject)))
        {
            if (EnableShadow(obj))
            {
                UnityEngine.Debug.Log("启用阴影 " + obj.name);
            }
        }
    }

    public static bool EnableShadow(GameObject go)
    {
        var mr = go.GetComponent<MeshRenderer>();
        var smr = go.GetComponent<SkinnedMeshRenderer>();
        if (mr != null)
        {
            if (mr.enabled && (!mr.castShadows || !mr.receiveShadows))
            {
                mr.castShadows = true;
                mr.receiveShadows = true;
                return true;
            }
        }
        return true;
    }
}